<html>
<head><meta charset="utf-8"><title>Adding variants to enums that are matched using a catch-all · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Adding.20variants.20to.20enums.20that.20are.20matched.20using.20a.20catch-all.html">Adding variants to enums that are matched using a catch-all</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="231253901"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Adding%20variants%20to%20enums%20that%20are%20matched%20using%20a%20catch-all/near/231253901" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Adding.20variants.20to.20enums.20that.20are.20matched.20using.20a.20catch-all.html#231253901">(Mar 22 2021 at 01:28)</a>:</h4>
<p>During a recent training, someone asked if there is some way of avoiding footguns when using the catch-all pattern. </p>
<p>As a concrete example, here we start with two variants and all the cases are handled. If we add a third variant, the compiler won't warn us about the <code>match</code> because we <em>are</em> handling the new case, but the programmer actually wanted to be forced to look at each match to decide if the catch-all was appropriate: </p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">enum</span> <span class="nc">Letter</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">Alpha</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="n">Beta</span><span class="p">,</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">fn</span> <span class="nf">in_a_function_far_away_from_the_enum_definition</span><span class="p">(</span><span class="n">l</span>: <span class="nc">Letter</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">match</span><span class="w"> </span><span class="n">l</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">Letter</span>::<span class="n">Alpha</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="cm">/* do something */</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w">        </span><span class="n">_</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="cm">/* do something */</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>I didn't have a great answer other than "don't use a catch-all", which felt like a cop-out answer. Any thoughts?</p>



<a name="231253930"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Adding%20variants%20to%20enums%20that%20are%20matched%20using%20a%20catch-all/near/231253930" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Adding.20variants.20to.20enums.20that.20are.20matched.20using.20a.20catch-all.html#231253930">(Mar 22 2021 at 01:29)</a>:</h4>
<blockquote>
<p>I didn't have a great answer other than "don't use a catch-all", which felt like a cop-out answer. Any thoughts?</p>
</blockquote>
<p>I mean, I do think that's the right answer, but if it helps I opened <a href="https://github.com/rust-lang/rust/issues/75235">https://github.com/rust-lang/rust/issues/75235</a> a while ago to have the compiler suggest how to remove the catch-all</p>



<a name="231254317"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Adding%20variants%20to%20enums%20that%20are%20matched%20using%20a%20catch-all/near/231254317" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Adding.20variants.20to.20enums.20that.20are.20matched.20using.20a.20catch-all.html#231254317">(Mar 22 2021 at 01:37)</a>:</h4>
<p>(concur with <span class="user-mention" data-user-id="116122">@simulacrum</span>'s point about Clippy first)</p>



<a name="231254380"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Adding%20variants%20to%20enums%20that%20are%20matched%20using%20a%20catch-all/near/231254380" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Adding.20variants.20to.20enums.20that.20are.20matched.20using.20a.20catch-all.html#231254380">(Mar 22 2021 at 01:38)</a>:</h4>
<p>I think a key difference in their question and your issue is that they are probably using the catch-all to apply to more than one variant.</p>



<a name="231254547"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Adding%20variants%20to%20enums%20that%20are%20matched%20using%20a%20catch-all/near/231254547" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Noah Lev <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Adding.20variants.20to.20enums.20that.20are.20matched.20using.20a.20catch-all.html#231254547">(Mar 22 2021 at 01:42)</a>:</h4>
<p><span class="user-mention silent" data-user-id="116155">Jake Goulding</span> <a href="#narrow/stream/122651-general/topic/Adding.20variants.20to.20enums.20that.20are.20matched.20using.20a.20catch-all/near/231254380">said</a>:</p>
<blockquote>
<p>I think a key difference in their question and your issue is that they are probably using the catch-all to apply to more than one variant.</p>
</blockquote>
<p>I often use or-patterns like <code>Beta | Gamma | Delta</code> instead of wildcards if I want to ensure I get compiler errors when more variants are added.</p>



<a name="231254572"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Adding%20variants%20to%20enums%20that%20are%20matched%20using%20a%20catch-all/near/231254572" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Adding.20variants.20to.20enums.20that.20are.20matched.20using.20a.20catch-all.html#231254572">(Mar 22 2021 at 01:43)</a>:</h4>
<p>Yep, that's basically what I suggested. I think the "problem" with that is that you need to know ahead of time that you want those compiler errors. This seems like it would lead to a broad suggestion to just never use a catch-all to start with.</p>



<a name="231254737"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Adding%20variants%20to%20enums%20that%20are%20matched%20using%20a%20catch-all/near/231254737" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Noah Lev <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Adding.20variants.20to.20enums.20that.20are.20matched.20using.20a.20catch-all.html#231254737">(Mar 22 2021 at 01:47)</a>:</h4>
<blockquote>
<p>I think the "problem" with that is that you need to know ahead of time that you want those compiler errors. This seems like it would lead to a broad suggestion to just never use a catch-all to start with.</p>
</blockquote>
<p>Yeah, I use top-level wildcards (<code>_ =&gt;</code>), but I think I use the or-patterns approach significantly more. I prefer the compiler errors even if they can be excessive :)</p>



<a name="231255076"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Adding%20variants%20to%20enums%20that%20are%20matched%20using%20a%20catch-all/near/231255076" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Adding.20variants.20to.20enums.20that.20are.20matched.20using.20a.20catch-all.html#231255076">(Mar 22 2021 at 01:54)</a>:</h4>
<p>Same for me, but why is it that I'd feel bad about making a sweeping proclamation like "never use wildcard pattens"?</p>



<a name="231255440"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Adding%20variants%20to%20enums%20that%20are%20matched%20using%20a%20catch-all/near/231255440" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Noah Lev <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Adding.20variants.20to.20enums.20that.20are.20matched.20using.20a.20catch-all.html#231255440">(Mar 22 2021 at 02:01)</a>:</h4>
<blockquote>
<p>why is it that I'd feel bad about making a sweeping proclamation like "never use wildcard pattens"?</p>
</blockquote>
<p>Wildcard patterns certainly have their uses, especially when matching on tuples like:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">match</span><span class="w"> </span><span class="p">(</span><span class="n">foo1</span><span class="p">,</span><span class="w"> </span><span class="n">foo2</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="p">(</span><span class="n">Foo</span>::<span class="n">A</span><span class="p">,</span><span class="w"> </span><span class="n">Foo</span>::<span class="n">A</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="o">..</span><span class="p">.,</span><span class="w"></span>
<span class="w">    </span><span class="p">(</span><span class="n">Foo</span>::<span class="n">B</span><span class="p">,</span><span class="w"> </span><span class="n">Foo</span>::<span class="n">B</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="o">..</span><span class="p">.,</span><span class="w"></span>
<span class="w">    </span><span class="p">(</span><span class="n">_</span><span class="p">,</span><span class="w"> </span><span class="n">_</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="cm">/* error */</span><span class="p">,</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="231255446"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Adding%20variants%20to%20enums%20that%20are%20matched%20using%20a%20catch-all/near/231255446" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Noah Lev <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Adding.20variants.20to.20enums.20that.20are.20matched.20using.20a.20catch-all.html#231255446">(Mar 22 2021 at 02:01)</a>:</h4>
<p>I think the answer is "it depends" ;)</p>



<a name="231294068"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Adding%20variants%20to%20enums%20that%20are%20matched%20using%20a%20catch-all/near/231294068" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Adding.20variants.20to.20enums.20that.20are.20matched.20using.20a.20catch-all.html#231294068">(Mar 22 2021 at 11:22)</a>:</h4>
<p>Although in that example you will be silently breaking if <code>Foo::C</code> is added (assuming that's an implementation of <code>PartialEq</code> or similar)</p>



<a name="231381151"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Adding%20variants%20to%20enums%20that%20are%20matched%20using%20a%20catch-all/near/231381151" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Noah Lev <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Adding.20variants.20to.20enums.20that.20are.20matched.20using.20a.20catch-all.html#231381151">(Mar 22 2021 at 20:41)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/122651-general/topic/Adding.20variants.20to.20enums.20that.20are.20matched.20using.20a.20catch-all/near/231294068">said</a>:</p>
<blockquote>
<p>Although in that example you will be silently breaking if <code>Foo::C</code> is added (assuming that's an implementation of <code>PartialEq</code> or similar)</p>
</blockquote>
<p>Actually it's an abstracted version of type unification, which is basically <code>PartialEq</code> for type systems <span aria-label="upside down" class="emoji emoji-1f643" role="img" title="upside down">:upside_down:</span></p>



<a name="231381239"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Adding%20variants%20to%20enums%20that%20are%20matched%20using%20a%20catch-all/near/231381239" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Noah Lev <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Adding.20variants.20to.20enums.20that.20are.20matched.20using.20a.20catch-all.html#231381239">(Mar 22 2021 at 20:42)</a>:</h4>
<p>But, yeah, it will break if <code>Foo::C</code> is added, which is annoying. But I don't know of any better way to do it without listing out all the n^2 permutations of the variants...</p>



<a name="232804865"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Adding%20variants%20to%20enums%20that%20are%20matched%20using%20a%20catch-all/near/232804865" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Adding.20variants.20to.20enums.20that.20are.20matched.20using.20a.20catch-all.html#232804865">(Apr 01 2021 at 18:41)</a>:</h4>
<p><code>PartialEq</code> is exactly where I have experienced (and still do)  this problem.</p>



<a name="232804967"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Adding%20variants%20to%20enums%20that%20are%20matched%20using%20a%20catch-all/near/232804967" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Adding.20variants.20to.20enums.20that.20are.20matched.20using.20a.20catch-all.html#232804967">(Apr 01 2021 at 18:42)</a>:</h4>
<p>So much so that I wrote a macro to write out the implementation of <code>PartialEq</code></p>



<a name="232805570"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Adding%20variants%20to%20enums%20that%20are%20matched%20using%20a%20catch-all/near/232805570" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Adding.20variants.20to.20enums.20that.20are.20matched.20using.20a.20catch-all.html#232805570">(Apr 01 2021 at 18:45)</a>:</h4>
<p>It'd be nice if</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="cp">#[derive(PartialEq)]</span><span class="w"></span>
<span class="k">enum</span> <span class="nc">A</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">X</span><span class="p">(</span><span class="n">T</span><span class="p">),</span><span class="w"></span>
<span class="w">    </span><span class="n">Y</span><span class="p">(</span><span class="n">T</span><span class="p">),</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>generated <code>impl &lt;T: PartialEq&lt;U&gt;, U&gt; PartialEq&lt;A&lt;U&gt;&gt; for A&lt;T&gt;</code></p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>